package service

import (
	"errors"
	"fmt"
	"github.com/vueadmin/app/admin/internal/dto"
	"github.com/vueadmin/app/admin/internal/model"
	"github.com/vueadmin/app/admin/internal/svc"
	"github.com/vueadmin/app/admin/internal/vo"
	"github.com/vueadmin/pkg/cache"
	"github.com/vueadmin/utils/conv"
	"gorm.io/gorm"
	"time"
)

type membeService struct {
	svcCtx *svc.ServiceContext
}

func NewMembeService(svcCtx *svc.ServiceContext) *membeService {
	return &membeService{
		svcCtx: svcCtx,
	}
}

/**
 * @description(数据列表)
 * @buildcode(true)
*/
func (p membeService) GetPageList(req *dto.MembePageReq) ([]*vo.MembeList, int64, error) {
	var (
		entity model.Membe
		list  []*vo.MembeList
		count int64
	)
	query := p.svcCtx.Db.Model(&entity)
	if !conv.IsEmpty(req.MembeId) {
		query = query.Where("membe_id = ?", req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		query = query.Where("username = ?", req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		query = query.Where("sex = ?", req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		query = query.Where("mobile = ?", req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		query = query.Where("email = ?", req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.Ssq){
		query = query.Where("ssq like ?", "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime){
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	orderBy := "membe_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		orderBy = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	query.Count(&count)
	if err := query.Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Order(orderBy).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	return list, count, nil
}

/**
 * @description(修改排序开关)
 * @buildcode(true)
*/
func (p membeService) UpdateExt(req map[string]interface{}) error {
	entity := model.Membe{}
	if err := p.svcCtx.Db.Model(&entity).Where("membe_id",conv.Int(req["membe_id"])).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(添加)
 * @buildcode(true)
*/
func (p membeService) Add(req *dto.MembeAddReq) (int, error) {
	entity := model.Membe{}
	entity.Username = req.Username
	entity.Sex = req.Sex
	entity.Mobile = req.Mobile
	entity.Pic = req.Pic
	entity.Email = req.Email
	entity.Password = conv.EncryptPassword(req.Password)
	entity.Amount = req.Amount
	entity.Status = req.Status
	entity.Ssq = req.Ssq
	entity.CreateTime = conv.NowUnix()

	if err := p.svcCtx.Db.Create(&entity).Error; err != nil {
		return 0, err
	}
	return entity.MembeId, nil
}

/**
 * @description(修改)
 * @buildcode(true)
*/
func (p membeService) Update(req *dto.MembeUpdateReq) error {
	entity := model.Membe{
		MembeId: req.MembeId,
	}
	query := p.svcCtx.Db
	if err := query.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	entity.Username = req.Username
	entity.Sex = req.Sex
	entity.Mobile = req.Mobile
	entity.Pic = req.Pic
	entity.Email = req.Email
	entity.Amount = req.Amount
	entity.Status = req.Status
	entity.Ssq = req.Ssq
	entity.CreateTime = conv.UnixTime(req.CreateTime)

	field := conv.StringToSlice("username,sex,mobile,pic,email,amount,status,ssq,create_time", ",")

	if err := query.Select(field).Updates(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取修改详情)
 * @buildcode(true)
*/
func (p membeService) GetUpdateInfo(req *dto.MembeGetUpdateInfoReq) (*model.Membe, error) {
	entity := model.Membe{}
	if err := p.svcCtx.Db.Where("membe_id = ?",req.MembeId).Limit(1).First(&entity).Error; err != nil {
		return nil, err
	}
	return &entity, nil
}

/**
 * @description(删除)
 * @buildcode(true)
*/
func (p membeService) Delete(req *dto.MembeDeleteReq) error {
	query := p.svcCtx.Db
	query = query.Where("membe_id IN ?", req.MembeId)
	if err := query.Delete(&model.Membe{}).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(查看详情)
 * @buildcode(true)
*/
func (p membeService) Detail(req *dto.MembeDetailReq) (*vo.MembeDetail, error) {
	var info vo.MembeDetail
	query := p.svcCtx.Db.Model(&model.Membe{})
	if err := query.Where("membe_id = ?",req.MembeId).Limit(1).First(&info).Error; err != nil {
		return nil, err
	}
	return &info, nil
}

/**
 * @description(重置密码)
 * @buildcode(true)
*/
func (p membeService) ResetPwd(req *dto.MembeResetPwdReq) error {
	entity := model.Membe{
		MembeId: conv.Int(req.MembeId),
	}
	query := p.svcCtx.Db
	if err := query.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	if err := query.Model(&entity).Update("password",conv.EncryptPassword(req.Password)).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(导入)
 * @buildcode(true)
*/
func (p membeService) Import(req []dto.MembeImportReq) error {
	var entity []*model.Membe
	for _, v := range req {
		entity = append(entity, &model.Membe{
			Username : conv.String(v.Username),
			Sex : conv.Int(conv.GetValByKey(v.Sex,`[{"key":"男","label_color":"primary","val":1},{"key":"女","label_color":"warning","val":2}]`)),
			Mobile : conv.String(v.Mobile),
			Pic : conv.String(v.Pic),
			Email : conv.String(v.Email),
			Password : conv.EncryptPassword(v.Password),
			Amount : conv.Float64(v.Amount),
			Status : conv.Int8(conv.GetValByKey(v.Status,`[{"key":"正常","label_color":"primary","val":1},{"key":"禁用","label_color":"danger","val":0}]`)),
			Ssq : conv.StringToSlice(v.Ssq,"-"),
			CreateTime : conv.NowUnix(),
		})
	}

	if err := p.svcCtx.Db.Create(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(客户端导出)
 * @buildcode(true)
*/
func (p membeService) Export(req *dto.MembePageReq) ([]*vo.MembeExport,int64, error) {
	var (
		list []*vo.MembeExport
		count int64
	)
	where := "1=1 "
	if !conv.IsEmpty(req.MembeId) {
		where += fmt.Sprintf(`and membe_id = %d `, *req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		where += fmt.Sprintf(`and username = "%s" `, req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		where += fmt.Sprintf(`and sex = %d `, req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		where += fmt.Sprintf(`and mobile = "%s" `, req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		where += fmt.Sprintf(`and email = "%s" `, req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		where += fmt.Sprintf(`and status = %d `, *req.Status)
	}
	if !conv.IsEmpty(req.Ssq){
		where += fmt.Sprintf(`and ssq like "%s" `, "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime){
		where += fmt.Sprintf(`and create_time BETWEEN %d AND %d `, conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	order := "membe_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	skip := (req.Page - 1) * req.Limit
	sql := fmt.Sprintf(`select * from cd_membe where %s order by %s limit %d,%d`, where,order,skip, req.Limit)
	if err := p.svcCtx.Db.Raw(sql).Scan(&list).Error; err != nil {
		return nil,0,err
	}
	for k,v := range list{
		list[k].Sex = conv.GetItemVal(v.Sex,`[{"key":"男","label_color":"primary","val":1},{"key":"女","label_color":"warning","val":2}]`)
		list[k].Status = conv.GetItemVal(v.Status,`[{"key":"正常","label_color":"primary","val":1},{"key":"禁用","label_color":"danger","val":0}]`)
		list[k].CreateTime = conv.DateTime(conv.Int64(v.CreateTime))
	}
	if req.Page == 1{
		cache.New(p.svcCtx.Redis).Delete("membe_count")
	}
	cache_count := cache.New(p.svcCtx.Redis).Get("membe_count")
	if cache_count == "" {
		countSql := fmt.Sprintf(`select count(*) as count from (select * from cd_membe where %s) as tmp`, where)
		p.svcCtx.Db.Raw(countSql).Scan(&count)
		cache.New(p.svcCtx.Redis).Set("membe_count", conv.String(count), 300*time.Second)
	} else {
		count = conv.Int64(cache_count)
	}
	return list,count, nil
}

/**
 * @description(充值)
 * @buildcode(true)
*/
func (p membeService) Jia(req *dto.MembeJiaReq) error {
	entity := model.Membe{
		MembeId: conv.Int(req.MembeId),
	}
	query := p.svcCtx.Db
	if err := query.Model(&entity).Update("amount",gorm.Expr("amount + ?", req.Amount)).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(扣除)
 * @buildcode(true)
*/
func (p membeService) Jian(req *dto.MembeJianReq) error {
	entity := model.Membe{
		MembeId: conv.Int(req.MembeId),
	}
	query := p.svcCtx.Db
	if err := query.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	if req.Amount > entity.Amount{
		return errors.New("数据不足!")
	}
	if err := query.Model(&entity).Update("amount",gorm.Expr("amount - ?", req.Amount)).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(状态禁用)
 * @buildcode(true)
*/
func (p membeService) Forbidden(req *dto.MembeForbiddenReq) error {
	entity := model.Membe{}
	query := p.svcCtx.Db
	if err := query.Model(&entity).Where("membe_id IN ?", req.MembeId).Update("status","0").Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取积分汇总)
 * @buildcode(true)
*/
func (p membeService) GetAmountSum(req *dto.MembePageReq) float64 {
	var (
		entity model.Membe
		sum float64
	)
	query := p.svcCtx.Db.Model(&entity)
	if !conv.IsEmpty(req.MembeId) {
		query = query.Where("membe_id = ?", req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		query = query.Where("username = ?", req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		query = query.Where("sex = ?", req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		query = query.Where("mobile = ?", req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		query = query.Where("email = ?", req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.Ssq){
		query = query.Where("ssq like ?", "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime){
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	query.Select("sum(amount)").Scan(&sum)
	return sum
}

